/** 
    @file pixelobj.hpp
    @brief Game object
*/

#ifndef PM3_PIXELOBJ_HPP
#define PM3_PIXELOBJ_HPP

#include "lua/lua_scripted.hpp"
#include "interface.hpp"
#include "util.hpp"
#include "pixelnode.hpp"

namespace pm3 {
    /**
        @class PIXELOBJ
        @brief Game object
    */
    class PIXELOBJ: public LUA_SCRIPTED {
    friend class PIXELMAP;
    friend class PIXELROOM;
    public:
            /**
                @brief Constructor
            */
            PIXELOBJ();
            /**
                @brief Destructor
            */
            ~PIXELOBJ();

            /**
                @brief Assignment operator
            */
            PIXELOBJ& operator=( const PIXELOBJ &r_obj );

            /**
                @brief Unloads the luascript
            */
            void unload();

            /**
                @brief Gets tags associated with the object
                @return A string containing the tags
            */
            inline std::string get_tags() const {
                return m_tags;
            }

            /**
                @brief Adds tags to the object
                @param[in] r_tags Reference to comma separated tags to be added
            */
            inline void add_tags( const std::string &r_tags ) {
                m_tags = pm3::util::add_tags( m_tags, r_tags );
            }

            /**
                @brief Removes tags from the object
                @param[in] r_tags Reference to comma separated tags to be removed
            */
            inline void remove_tags( const std::string &r_tags ) {
                m_tags = pm3::util::remove_tags( m_tags, r_tags );
            }

            /**
                @brief Gets directions of the object
                @return An integer ORed with direction tags
            */
            inline int get_directions() const {
                return m_directions;
            }

            /**
                @brief Gets the pixel color of the object
                @return Pixel color
            */
            inline Ogre::ColourValue get_color() const {
                return m_color;
            }

            /**
                @brief Updates the object
            */
            void update();

            /**
                @brief Saves object script As
                @param[in] r_path Path to the script
                @return Path to the script on success, empty string on failure
            */
            std::string save_script( const std::string &r_path );

            /**
                @brief Saves object script
                @return Path to the script on success, empty string on failure
            */
            inline std::string save_script() {
                return save_script( m_script_path );
            }

            /**
                @brief Updates script snippet variables
            */
            void update_script_snippets();

            //! Global script in Lua
            std::string m_global_script;
            //! Instance callback in Lua
            std::string m_instance_script;
            //! Player-entered callback in Lua
            std::string m_player_entered_script;

    protected:
            //! Pixel color that corresponds to the object
            Ogre::ColourValue m_color;
            //! Direction flags
            int m_directions;

            /**
                @brief Binds functions called by lua
            */
            void bind();

            /**
                @brief Sets up an instance for a node
                @param[in] p_node Pointer to the node
                @param[in] r_grid_pos Reference to node grid position
            */
            void instance_setup( PIXELNODE *p_node, const Ogre::Vector3 &r_grid_pos );

            /**
                @brief Calls the enter() lua function in the objectscript
                @param[in] i_layer Layer index
                @param[in] i_x X-coordinate in grid coordinates
                @param[in] i_y Y-coordinate in grid coordinates
                @note Should be called from map update
            */
            void enter_room( int i_layer, int i_x, int i_y );

    private:
            //! Object tags
            std::string m_tags;
    };

    namespace lua {
        //! Pointer to the active object to which all called lua functions apply
        extern PIXELOBJ *g_active_obj;
    }
}

#endif

